package org.lazy.generate.factory;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.sql.ResultSetMetaData;
import java.util.HashSet;
import java.util.Set;

import org.lazy.generate.bean.GeneratorDao;
import org.lazy.generate.bean.GeneratorDataSource;
import org.lazy.generate.bean.GeneratorEntity;
import org.lazy.generate.bean.GeneratorService;
import org.lazy.generate.bean.GeneratorTable;
import org.lazy.generate.common.XmlConstants;
import org.lazy.generate.util.FactoryUtil;

public class ServiceFactory extends FileFactory{
	/**
	 * 生成Service接口
	 */
	public static void buildService(GeneratorDataSource dataSource,GeneratorEntity entity,GeneratorDao dao,GeneratorService service,GeneratorTable table,ResultSetMetaData metaData) throws Exception{
		if(XmlConstants.IS_NEED_FALSE.equals(service.getIsNeed())){
			System.out.println("ignore : "+table.getTableName()+" build Service");
			return;
		}
		String tableName = table.getTableName();
		String entityName = table.getEntityName();
		String entityClassName = createEntityClassName(entityName, tableName);
		String serviceClassName = createServiceClassName(entityClassName, tableName);
		String servicePackage = service.getTargetPackage();
		String targetPath = service.getTargetPath();
		String serviceFilePath = targetPath+"/"+servicePackage.replace(".", "/");
		PrintWriter pw = null;
		File file = createTargetClass(serviceFilePath, serviceClassName);
		try {
			pw = new PrintWriter(file);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		//package
		pw.println("package "+servicePackage+";\n");
		Set<String> importClasses = needImportToService(entity,service, table);
		writeImportClass(pw, importClasses);
		pw.println("");
		//class
		pw.println("public interface "+serviceClassName+" {\t");
		writeToService(pw,dataSource, entity, service, table, metaData);
		pw.println("}");
		pw.flush();
		pw.close();
		System.out.println("success : "+serviceClassName+".java");
	}
	/**
	 * 生成Service接口实现类ServiceImpl
	 */
	public static void buildServiceImpl(GeneratorDataSource dataSource,GeneratorEntity entity,GeneratorDao dao,GeneratorService service,GeneratorTable table,ResultSetMetaData metaData) throws Exception{
		if(XmlConstants.IS_NEED_FALSE.equals(service.getIsNeed())){
			System.out.println("ignore : "+table.getTableName()+" build ServiceImpl");
			return;
		}
		String tableName = table.getTableName();
		String entityName = table.getEntityName();
		String entityClassName = createEntityClassName(entityName, tableName);
		String serviceClassName = createServiceClassName(entityClassName, tableName);
		String serviceImplClassName = createServiceImplClassName(entityClassName, tableName);
		String serviceImplPackage = service.getTargetPackage()+".impl";
		String targetPath = service.getTargetPath();
		String serviceImplFilePath = targetPath+"/"+serviceImplPackage.replace(".", "/");
		PrintWriter pw = null;
		File file = createTargetClass(serviceImplFilePath, serviceImplClassName);
		try {
			pw = new PrintWriter(file);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		//package
		pw.println("package "+serviceImplPackage+";\n");
		Set<String> importClasses = needImportToServiceImpl(entity,dao,service, table);
		writeImportClass(pw, importClasses);
		pw.println("");
		//class
		pw.println("@Service(\""+lowerCaseFirstAlphabet(serviceClassName)+"\")");
		pw.println("public class "+serviceImplClassName+"  implements  "+serviceClassName+" {\t");
		writeToServiceImpl(pw, dataSource,entity, service, table, metaData);
		pw.println("}");
		pw.flush();
		pw.close();
		System.out.println("success : "+serviceImplClassName+".java");
	}
	/**
	 * 生成ServiceExt接口
	 */
	public static void buildServiceExt(GeneratorDataSource dataSource,GeneratorService service,GeneratorTable table,ResultSetMetaData metaData) throws Exception{
		if(XmlConstants.IS_NEED_FALSE.equals(service.getIsNeed())){
			System.out.println("ignore : "+table.getTableName()+" build ServiceExt");
			return ;
		}
		String tableName = table.getTableName();
		String entityName = table.getEntityName();
		String entityClassName = createEntityClassName(entityName, tableName);
		String serviceClassName = createServiceClassName(entityClassName, tableName);
		String serviceExtClassName = createServiceExtClassName(entityClassName, tableName);
		String targetPath = service.getTargetPath();
		String serviceExtPackage = service.getTargetPackage();
		String serviceExtFilePath = targetPath+"/"+serviceExtPackage.replace(".", "/");
		PrintWriter pw = null;
		if(!isExistJavaFile(serviceExtFilePath, serviceExtClassName)){
			File file = createTargetClass(serviceExtFilePath, serviceExtClassName);
			try {
				pw = new PrintWriter(file);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			//package
			pw.println("package "+serviceExtPackage+";\n");
			pw.println("");
			//class
			pw.println("public interface "+serviceExtClassName+" extends "+serviceClassName+"{\t");
			
			pw.println("}");
			pw.flush();
			pw.close();
			System.out.println("success : "+serviceExtClassName+".java");
		}
		
	}
	/**
	 * 生成ServiceExt接口实现类ServiceImplExt
	 */
	public static void buildServiceImplExt(GeneratorDataSource dataSource,GeneratorService service,GeneratorTable table,ResultSetMetaData metaData) throws Exception{
		if(XmlConstants.IS_NEED_FALSE.equals(service.getIsNeed())){
			System.out.println("ignore : "+table.getTableName()+" build ServiceImplExt");
			return;
		}
		String tableName = table.getTableName();
		String entityName = table.getEntityName();
		String entityClassName = createEntityClassName(entityName, tableName);
		String serviceImplClassName = createServiceImplClassName(entityClassName, tableName);
		String serviceExtClassName = createServiceExtClassName(entityClassName, tableName);
		String serviceImplExtClassName = createServiceImplExtClassName(entityClassName, tableName);
		String targetPath = service.getTargetPath();
		String serviceImplExtPackage = service.getTargetPackage()+".impl";
		String serviceImplExtFilePath = targetPath+"/"+serviceImplExtPackage.replace(".", "/");
		PrintWriter pw = null;
		if(!isExistJavaFile(serviceImplExtFilePath, serviceImplExtClassName)){
			File file = createTargetClass(serviceImplExtFilePath, serviceImplExtClassName);
			try {
				pw = new PrintWriter(file);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			//package
			pw.println("package "+serviceImplExtPackage+";\n");
			pw.println("import org.springframework.stereotype.Service;\n");
			pw.println("import "+service.getTargetPackage()+"."+serviceExtClassName+";");
			pw.println("");
			//class
			pw.println("@Service(\""+lowerCaseFirstAlphabet(serviceExtClassName)+"\")");
			pw.println("public class "+serviceImplExtClassName+" extends "+serviceImplClassName+"  implements  "+serviceExtClassName+" {\t");
			
			pw.println("}");
			pw.flush();
			pw.close();
			System.out.println("success : "+serviceImplExtClassName+".java");
		}
	}
	
	private static void writeToService(PrintWriter pw,GeneratorDataSource dataSource,GeneratorEntity entity,GeneratorService service,GeneratorTable table,ResultSetMetaData metaData) throws Exception{
		String tableName = table.getTableName();
		String entityName = table.getEntityName();
		String dbType = dataSource.getDbType();
		String entityClassName = createEntityClassName(entityName, tableName);
		String entityConditionClassName = createEntityConditionClassName(entityName, tableName);
		String primaryKeyJavaType = FactoryUtil.getPrimaryKeyJaveType(table, metaData, dbType);
		pw.println(t1+"public boolean "+s_method_save+"("+entityClassName+" "+entityClassName.toLowerCase()+");");
		pw.println(t1+"public "+entityClassName+" "+s_method_findByPrimaryKey+"("+primaryKeyJavaType+" id);");
		pw.println(t1+"public List<"+entityClassName+"> "+s_method_findByCondition+"("+entityConditionClassName+" condition);");
		pw.println(t1+"public Page "+s_method_findPageByCondition+"("+entityConditionClassName+" condition);");
		pw.println(t1+"public boolean "+s_method_updateByPrimaryKey+"("+entityClassName+" "+entityClassName.toLowerCase()+");");
		pw.println(t1+"public boolean "+s_method_delByPrimaryKey+"("+primaryKeyJavaType+" id);");
		pw.println(t1+"public boolean "+s_method_delBatchByPrimaryKey+"(List<"+primaryKeyJavaType+"> ids);");
	}
	
	private static Set<String> needImportToService(GeneratorEntity entity,GeneratorService service,GeneratorTable table){
		Set<String> set = new HashSet<String>();
		String tableName = table.getTableName();
		String entityName = table.getEntityName();
		String entityClassName = createEntityClassName(entityName, tableName);
		String entityConditionClassName = createEntityConditionClassName(entityName, tableName);
		String entityPackage = entity.getTargetPackage();
		String entityClassNameFull = createFullEntityClassName(entityPackage, entityClassName);
		String entityClassConditionNameFull = createFullEntityClassName(entityPackage, entityConditionClassName);
		set.add("org.lazy.generate.common.Page");
		set.add("java.util.List");
		set.add(entityClassNameFull);
		set.add(entityClassConditionNameFull);
		return set;
	}
	private static void writeToServiceImpl(PrintWriter pw,GeneratorDataSource dataSource,GeneratorEntity entity,GeneratorService service,GeneratorTable table,ResultSetMetaData metaData) throws Exception{
		String tableName = table.getTableName();
		String entityName = table.getEntityName();
		String dbType = dataSource.getDbType();
		String entityClassName = createEntityClassName(entityName, tableName);
		String entityConditionClassName = createEntityConditionClassName(entityName, tableName);
		String primaryKeyJavaType = FactoryUtil.getPrimaryKeyJaveType(table, metaData, dbType);
		String daoExtClassName = createDaoExtClassName(entityClassName, tableName);
		String daoExtClassNameP = daoExtClassName.substring(0,1).toLowerCase()+daoExtClassName.substring(1);
		pw.println(t1+"@Autowired");
		pw.println(t1+"private "+daoExtClassName+" "+daoExtClassNameP+";");
		//save
		pw.println(t1+"public boolean "+s_method_save+"("+entityClassName+" "+entityClassName.toLowerCase()+") {");
		pw.println(t2+"return "+daoExtClassNameP+"."+d_method_insert+"("+entityClassName.toLowerCase()+");");
		pw.println(t1+"}");
		//findByPrimaryKey
		pw.println(t1+"public "+entityClassName+" "+s_method_findByPrimaryKey+"("+primaryKeyJavaType+" id) {");
		pw.println(t2+"return "+daoExtClassNameP+"."+d_method_selectByPrimaryKey+"(id);");
		pw.println(t1+"}");
		//findByCondition
		pw.println(t1+"public List<"+entityClassName+"> "+s_method_findByCondition+"("+entityConditionClassName+" condition) {");
		pw.println(t2+"return "+daoExtClassNameP+"."+d_method_selectByCondition+"(condition);");
		pw.println(t1+"}");
		//findPageByCondition
		pw.println(t1+"public Page "+s_method_findPageByCondition+"("+entityConditionClassName+" condition) {");
		pw.println(t2+"Page page = new Page(condition.getPageNo(), condition.getPageSize(), "+daoExtClassNameP+"."+d_method_countByCondition+"(condition), "+daoExtClassNameP+"."+d_method_selectByCondition+"(condition));");
		pw.println(t2+"return page;");
		pw.println(t1+"}");
		//updateByPrimaryKey
		pw.println(t1+"public boolean "+s_method_updateByPrimaryKey+"("+entityClassName+" "+entityClassName.toLowerCase()+") {");
		pw.println(t2+"return "+daoExtClassNameP+"."+d_method_updateByPrimaryKey+"("+entityClassName.toLowerCase()+");");
		pw.println(t1+"}");
		//delByPrimaryKey
		pw.println(t1+"public boolean "+s_method_delByPrimaryKey+"("+primaryKeyJavaType+" id) {");
		pw.println(t2+"return "+daoExtClassNameP+"."+d_method_deleteByPrimaryKey+"(id);");
		pw.println(t1+"}");
		//delBatchByPrimaryKey
		pw.println(t1+"public boolean "+s_method_delBatchByPrimaryKey+"(List<"+primaryKeyJavaType+"> ids) {");
		pw.println(t2+"return "+daoExtClassNameP+"."+d_method_deleteBatchByPrimaryKey+"(ids);");
		pw.println(t1+"}");

	}
	


	private static Set<String> needImportToServiceImpl(GeneratorEntity entity,GeneratorDao dao,GeneratorService service,GeneratorTable table){
		Set<String> set = new HashSet<String>();
		String tableName = table.getTableName();
		String entityName = table.getEntityName();
		String entityClassName = createEntityClassName(entityName, tableName);
		String entityConditionClassName = createEntityConditionClassName(entityName, tableName);
		String entityPackage = entity.getTargetPackage();
		String entityClassNameFull = createFullEntityClassName(entityPackage, entityClassName);
		String entityClassConditionNameFull = createFullEntityClassName(entityPackage, entityConditionClassName);
		String servicePackage = service.getTargetPackage();
		String serviceClassName = createServiceClassName(entityClassName, tableName);
		String serviceClassNameFull = createFullServiceClassName(servicePackage, serviceClassName);
		String daoPackage = dao.getTargetPackage();
		String daoExtClassName = createDaoExtClassName(entityClassName, tableName);
		String daoExtClassNameFull = createFullDaoClassName(daoPackage, daoExtClassName);
		set.add("java.util.List");
		set.add("org.springframework.stereotype.Service");
		set.add("org.springframework.beans.factory.annotation.Autowired");
		set.add("org.lazy.generate.common.Page");
		set.add(daoExtClassNameFull);
		set.add(serviceClassNameFull);
		set.add(entityClassNameFull);
		set.add(entityClassConditionNameFull);
		return set;
	}
}
